import pandas as pd
from sklearn.ensemble import IsolationForest
import matplotlib.pyplot as plt

#加载数据
file_path = r"C:\Users\18318\Desktop\goldstock_v2_cleaned.csv"
data = pd.read_csv(file_path)

#移除'Unnamed: 0'列，因为它通常是无用的索引列
data = data.drop(columns=['Unnamed: 0'])

#将'Date'列转换为datetime类型，然后转换为数值型特征（如果需要）
data['Date'] = pd.to_datetime(data['Date'])
data['Year'] = data['Date'].dt.year
data['Month'] = data['Date'].dt.month

#移除原始的'Date'列
data = data.drop(columns=['Date'])

#确保所有列都是数值型
for col in data.columns:
    if data[col].dtype == 'object':
        data[col] = pd.to_numeric(data[col], errors='coerce')

#移除任何包含NaN的行
data = data.dropna()

#使用IsolationForest检测异常值
clf = IsolationForest(contamination='auto', n_estimators=100, random_state=42)
clf.fit(data)

#预测数据集中每个点是否为异常值
predictions = clf.predict(data)

#将预测结果添加到原始数据框中
data['anomaly'] = predictions

#分离正常值和异常值
normal_data = data[data['anomaly'] == 1]
anomalies_data = data[data['anomaly'] == -1]

#可视化异常值和正常值的直方图
plt.figure(figsize=(14, 10))

#正常值的直方图
plt.subplot(2, 2, 1)
plt.hist(normal_data['Close/Last'], bins=30, alpha=0.5, label='Normal')
plt.title('Close/Last - Normal Distribution')

plt.subplot(2, 2, 2)
plt.hist(normal_data['Volume'], bins=30, alpha=0.5, label='Normal')
plt.title('Volume - Normal Distribution')

#异常值的直方图
plt.subplot(2, 2, 3)
plt.hist(anomalies_data['Close/Last'], bins=30, alpha=0.5, label='Anomalies')
plt.title('Close/Last - Anomalies')

plt.subplot(2, 2, 4)
plt.hist(anomalies_data['Volume'], bins=30, alpha=0.5, label='Anomalies')
plt.title('Volume - Anomalies')

plt.tight_layout()
plt.show()